#!/Users/martin/.pyenv/shims/python3
import requests
import json
import sys
import base64
import re
import configparser
import urllib3
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
import time

#disable InsecureWarning
urllib3.disable_warnings()

#read config.ini
configins = configparser.ConfigParser()
configins.read('config.ini')

#read netconf
ipaddr = configins['netconf']['ipaddr']
serverport = configins['netconf']['serverport']

#base dict set
requestdata = {}
requestdata['userID'] = configins['baseinfo']['userID']
requestdata['userPassword'] = configins['baseinfo']['userPassword']
requestdata['clientName'] = configins['baseinfo']['clientName']
processcheckwait = int(configins['baseinfo']['processcheckwait'])

#other func dict set

#api url set
apiurldata = {}
apiurldata['get_public_key'] = 'https://' + ipaddr + ':' + serverport + '/ctp/get_public_key'
apiurldata['LoginAccountPasswordModify'] = 'https://' + ipaddr + ':' + serverport + '/ctp/LoginAccountPassword/Modify'
apiurldata['InvestorFutCommRateQuery'] = 'https://' + ipaddr + ':' + serverport + '/ctp/InvestorFutCommRate/Query'
apiurldata['CurrentStatusQuery'] = 'https://' + ipaddr + ':' + serverport + '/ctp/CurrentStatus/Query'


#open session for api
mainsession = requests.session()


#regex set
mesgmatchstr = '.*?maxMessageNo.*?([0-9]+)'
mesgre = re.compile(mesgmatchstr)

def passwdencrypt(pwstr, publickey):
	pwstr = pwstr.encode('utf-8')
	keyPub = RSA.import_key(base64.b64decode(publickey))
	cipher = Cipher_pkcs1_v1_5.new(keyPub)
	encryptpwd = base64.b64encode(cipher.encrypt(pwstr))
	return encryptpwd.decode('utf-8')

def getmaxmesgno(requestdata):
	rqdata = {}
	rqdata['userID'] = requestdata['userID']
	rqdata['commType'] = 'get_public_key'
	rqdata['messageNo'] = '1'
	rc = mainsession.post(url=apiurldata['get_public_key'], json=rqdata, verify=False)
	#ctpapi change, rcdict redirect to list[0]
	rcdict = json.loads(rc.text)[0]
	if(rcdict['errorNo'] == 0):
		print('get max mesgno ok, today first login, maxmsgno: 1')
		return 1
	elif('errorInfo' in rcdict.keys()):
		errormsg = rcdict['errorInfo']
		catchgroup = re.search(mesgre, errormsg)
		maxno = int(catchgroup.groups()[0]) + 1
		print('get max mesgno ok, maxmsgno: ', catchgroup.groups()[0])
		return maxno
	else:
		print('get max mesgno failed, please check error detail:')
		print(rc.text)
		return -1

def rctextparse(rctext):
	rcstore = json.loads(rctext)
	#search dict from outlist
	while(type(rcstore) == list):
		rcstore = rcstore[0]

	#type check
	if(type(rcstore) != dict):
		print("return text can not transfer to dict")
		return
	
	#errorNo check
	if('errorNo' in rcstore):
		rcstore['errorNo'] = int(rcstore['errorNo'])
	else:
		print("no errorNo in result!")
		return
	if(rcstore['errorNo'] != 0):
		print("return ERROR!!!")
		print("errorNo=", rcstore['errorNo'], " errorInfo=", rcstore['errorInfo'])
		return
	else:
		print("request success!!!")
		print("errorNo=", rcstore['errorNo'], " errorInfo=", rcstore['errorInfo'])
	
	#resultList parse
	if('resultList' in rcstore):
		tmplist = rcstore['resultList']
		print("*" * 10, "resultList dataprint", "*" * 10)
		for currdata in tmplist:
			print(currdata)

	#processID parse
	if('processID' in rcstore):
		processid = rcstore['processID']
		time.sleep(processcheckwait)
		CurrentStatusQuery(requestdata, processid)

def CurrentStatusQuery(requestdata, processid):
	global mesgcount
	rqdata = {}
	#public para
	rqdata['userID'] = requestdata['userID']
	requestdata['messageNo'] = requestdata['messageNo'] + 1
	rqdata['userPassword'] = requestdata['userPassword']
	#ctpapi change, messageNo string type check
	rqdata['messageNo'] = str(requestdata['messageNo'])
	rqdata['clientName'] = requestdata['clientName']

	#bussiness para
	rqdata['processIDs'] = processid
	
	#request send
	rc = mainsession.post(url=apiurldata['CurrentStatusQuery'], json=rqdata, verify=False)

	#result parse
	rctextparse(rc.text)

def get_public_key(requestdata):
	global mesgcount
	rqdata = {}
	rqdata['userID'] = requestdata['userID']
	rqdata['commType'] = 'get_public_key'
	requestdata['messageNo'] = requestdata['messageNo'] + 1
	#ctpapi change, messageNo string type check
	rqdata['messageNo'] = str(requestdata['messageNo'])
	rc = mainsession.post(url=apiurldata['get_public_key'], json=rqdata, verify=False)	
	rcdict = json.loads(rc.text)
	print(rcdict)
	#ctpapi change. errorNo type trans
	rcdict['errorNo'] = int(rcdict['errorNo'])
	if(rcdict['errorNo'] == 0):
		print('get public key success!')
		publickey = rcdict['data']['publicKey']	
		return publickey
	else:
		print('get public key failed! please check detail:')
		print(rc.text)
		return 233

def InvestorFutCommRateQuery(requestdata):
	global mesgcount
	rqdata = {}
	#public para
	rqdata['userID'] = requestdata['userID']
	requestdata['messageNo'] = requestdata['messageNo'] + 1
	rqdata['userPassword'] = requestdata['userPassword']
	#ctpapi change, messageNo string type check
	rqdata['messageNo'] = str(requestdata['messageNo'])
	rqdata['clientName'] = requestdata['clientName']

	#bussiness para
	rqdata['QryInvestorFutCommRate'] = {}
	rqdata['QryInvestorFutCommRate']['tradingDay'] = configins['InvestorFutCommRateQuery']['tradingDay']
	rqdata['QryInvestorFutCommRate']['brokerID'] = configins['InvestorFutCommRateQuery']['brokerID']
	rqdata['QryInvestorFutCommRate']['investorID'] = configins['InvestorFutCommRateQuery']['investorID']
	rqdata['QryInvestorFutCommRate']['investUnitID'] = configins['InvestorFutCommRateQuery']['investUnitID']
	#before 3.0.2P2 update
	if(configins['InvestorFutCommRateQuery']['exchangeID'].strip() != ""):
		rqdata['QryInvestorFutCommRate']['exchangeID'] = configins['InvestorFutCommRateQuery']['exchangeID']
	if(configins['InvestorFutCommRateQuery']['instrumentID'].strip() != ""):
		rqdata['QryInvestorFutCommRate']['instrumentID'] = configins['InvestorFutCommRateQuery']['instrumentID']
	if(configins['InvestorFutCommRateQuery']['hedgeFlag'].strip() != ""):
		rqdata['QryInvestorFutCommRate']['hedgeFlag'] = configins['InvestorFutCommRateQuery']['hedgeFlag']

	#request send
	rc = mainsession.post(url=apiurldata['InvestorFutCommRateQuery'], json=rqdata, verify=False)

	#result parse
	rctextparse(rc.text)

def LoginAccountPasswordModify(requestdata):
	global mesgcount
	rqdata = {}
	#public para
	rqdata['userID'] = requestdata['userID']
	requestdata['messageNo'] = requestdata['messageNo'] + 1
	rqdata['userPassword'] = requestdata['userPassword']
	#ctpapi change, messageNo string type check
	rqdata['messageNo'] = str(requestdata['messageNo'])
	rqdata['clientName'] = requestdata['clientName']

	#bussiness para
	rqdata['LoginAccountPassword'] = {}
	rqdata['LoginAccountPassword']['brokerID'] =  configins['LoginAccountPasswordModify']['brokerID']
	rqdata['LoginAccountPassword']['investorID'] =  configins['LoginAccountPasswordModify']['investorID']
	rqdata['LoginAccountPassword']['investUnitID'] =  configins['LoginAccountPasswordModify']['investUnitID']
	rqdata['LoginAccountPassword']['loginAccountID'] =  configins['LoginAccountPasswordModify']['loginAccountID']
	rqdata['LoginAccountPassword']['loginAccountPassword'] =  configins['LoginAccountPasswordModify']['loginAccountPassword']

	#request send
	rc = mainsession.post(url=apiurldata['LoginAccountPasswordModify'], json=rqdata, verify=False)

	#result parse
	rctextparse(rc.text)

if(__name__ == '__main__'):
	requestdata['messageNo'] = getmaxmesgno(requestdata)
	publickey = get_public_key(requestdata)
	requestdata['userPassword'] = passwdencrypt(requestdata['userPassword'], publickey)

	#start read actionlist
	actionlist = []
	with open('actionlist.ini', 'r') as f:
		for singleaction in f:
			actionlist.append(singleaction.strip('\n'))
		f.close()

	for singleaction in actionlist:
		exec('rc = %s(requestdata)' % (singleaction))
		input()

mainsession.close()
